#include "thread_linux.h"
/* GNU is used here because varargs.h poses
 * a few problems, because you have to install
 * it seperately.
 */

struct varg {
	char type;
	void* content;
	struct varg* next;
};

void
decode(struct varg* vv, ...)
{
	struct varg* v = vv;
	while(v->next != NULL)
	{
		switch(v->type)
		{
			case 'd':
				printf("%d\n", *((int*) v->content));
				break;
			case 'f':
				printf("%f\n", *((float*) v->content));
				break;
			case 'c':
				printf("%c\n", *((char*) v->content));
				break;
			case 's':
				printf("%s\n", ((char*) v->content));
				break;
		}
		v = v->next;
	}
}

/* Arguments supported are:
 * d - integer
 * c - char
 * s - string
 */
void
thread_start(const char* args, ...)
{
	va_list ap;
	register int i;

	struct varg* v_origin = malloc(sizeof(struct varg));
	struct varg* v = v_origin;
	for(i = 0; i < strlen(args); i++)
	{
		v->next = malloc(sizeof(struct varg));
		v       = v->next;
	}
	v->next = NULL;
	v       = v_origin;

	va_start(ap, args);

	while(*args != '\0')
	{
		switch(*args)
		{
			case 'd':
			{
				v->type    = 'd';
				v->content = malloc(sizeof(int));
				*((int*) v->content) = va_arg(ap, int);
				v = v->next;
				break;
			}
			case 'f':
			{
				v->type    = 'f';
				v->content = malloc(sizeof(float));
				*((float*) v->content) = va_arg(ap, double);
				v = v->next;
				break;
			}
			case 'c':
			{
				v->type    = 'c';
				v->content = malloc(sizeof(char));
				*((char*) v->content) = va_arg(ap, int);
				v = v->next;
				break;
			}
			case 's':
			{
				v->type    = 's';
				char* buf  = (char*) va_arg(ap, const char*);
				v->content = malloc(sizeof(strlen(buf)));
				strcpy(v->content, buf);
				v = v->next;
				break;
			}
			default:
				//TODO: Handle errors better.
				break;
		}

		args++;
	}

	va_end(ap);
}
